package org.bambrikii.examples.rutext.lexer.custom;

import org.bambrikii.examples.rutext.lexer.ILexer;
import org.bambrikii.examples.rutext.lexer.impl.LexerBase;
import org.bambrikii.examples.rutext.parser.IParser;
import org.bambrikii.examples.rutext.parser.ParserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class IntegerPartLexer extends LexerBase<Double> {

	private static final Logger logger = LoggerFactory.getLogger(IntegerPartLexer.class);

	public IntegerPartLexer(IParser parser) {
		super(parser);
		addChild(new IntegerLexer(parser));
	}

	@Override
	public Double lex() throws ParserException {
		Double result = new Double(0);
		Long previousValue = null;
		Double additiveValue = new Double(0);
		boolean parserFound = false;
		int n = 0;
		while (hasNext()) {
			parserFound = false;
			for (ILexer<?> child : getChildren()) {
				Object obj = child.lex();
				if (obj != null) {
					n++;
					if (child instanceof IntegerLexer) {
						Long currentValue = (Long) obj;
						if (previousValue == null || currentValue < previousValue) {
							additiveValue = additiveValue.doubleValue() + currentValue;
							previousValue = currentValue;
							logger.debug("result:" + result + ", additiveValue: " + additiveValue + ", previousValue: "
									+ previousValue);
						} else {
							result = addDecimal(result, additiveValue, currentValue);
							additiveValue = new Double(0);
							previousValue = null;
							logger.debug("result:" + result + ", additiveValue: " + additiveValue + ", previousValue: "
									+ previousValue);
						}
					}
					parserFound = parserFound || true;
				}
			}
			if (!parserFound) {
				break;
			}
		}
		if (additiveValue > 0) {
			result = addDecimal(result, additiveValue, 1L);
		}
		if (n > 0) {
			return result;
		}
		return null;
	}

	private Double addDecimal(Double result, Double additiveValue, Long currentValue) {
		result = result + (additiveValue.doubleValue() == 0 ? 1 : additiveValue.doubleValue()) * currentValue;
		return result;
	}
}
